/********************************************************************

Write Date: 2015/04/20
Author: Apple
>>>> Create class NewPtr.
	
Modify Date: 2015/04/21
Author: Apple
>>>> Use C++11 new feature 'deleted function' to forbid the access to the 
     unsupported functions.
>>>> Add document to macro OOPNEW.

Modify Date: 2015/04/26
Author: Apple
>>>> Add const to the paremeter of copy constructor and copy assignment.

Modify Date: 2015/08/13
Author: Apple
>>>> Change macro NEWOBJ add a parameter to new operator to pass the Object's
     name.

*********************************************************************/
#pragma once
#include "ooputils_global.h"
#include "Ptr.h"



/**
 * Macro NEWOBJ provides an alias to create an Object/non-Object and get a 
 * related NewPtr.
 * Usage: NEWOBJ (YourType, Name) (Constructor-parameter-list)
 */
#ifndef NEWOBJ
#define NEWOBJ(__type__, __name__) (OOP::NewPtr< __type__ >) new (__name__) __type__
#endif
/**
 * Macro NEWOBJ_NONAME provides an alias to create an Object/non-Object and get a 
 * related NewPtr.
 * Usage: NEWOBJ_NONAME (YourType) (Constructor-parameter-list)
 */
#ifndef NEWOBJ_NONAME
#define NEWOBJ_NONAME(__type__) (OOP::NewPtr< __type__ >) new __type__
#endif



_NS_OOP_BEGIN



/**
 * Class NewPtr is for converting a pointer to a Ptr. For Object pointers, only
 * pointers to newly created object can be used. The class is used to solve the 
 * problem that an object is referenced by a Ptr in its constructor and cause it 
 * destroied at the end of constructor. 
 *
 * @remarks 2015/04/20, Apple
 */
template< class T >
class NewPtr : public Ptr< T >
{
public:

	/**
	 * Create a NewPtr pointing to a non-Object.
	 *
	 * @param p_data - a non-Object pointer
	 */
	NewPtr (void* p_data);

	/**
	 * Create a NewPtr pointing to an Object.
	 *
	 * @param p_data - an Object pointer
	 */
	NewPtr (Object* p_data);

	/* Functions below are forbidden */
	NewPtr (const NewPtr< T >& r_right) = delete;
	NewPtr (NewPtr< T >&& rr_right) = delete;
	NewPtr< T >& operator= (const NewPtr< T >& r_right) = delete;
	NewPtr< T >& operator= (NewPtr< T >&& rr_right) = delete;
};



_NS_OOP_END



#include "NewPtr.hpp"